<template>
  <div>
    <el-dialog
        title="提示"
        :visible.sync="dialogVisible"
        width="60%" @close="cancel">
      <el-table
          :data="tableData"
          ref="multipleTable"
          border
          row-key="id"
          :row-class-name="getRowClassName"
          :header-row-class-name="getHeaderRowClassName"
          default-expand-all
          size="mini"
          max-height="500px"
          style="width: 100%"
          @select="selectFun"
          @select-all="selectAllFun"
          @selection-change="selectionChangeFun"
          :header-cell-style="{ background: '#fafafa' }"
      >
        <el-table-column type="selection" width="55"> </el-table-column>
        <el-table-column
            prop="wbsms"
            label="WBS描述"
            align="center"
            show-overflow-tooltip
            >
        </el-table-column>
        <el-table-column
            prop="wbsys"
            label="WBS元素"
            align="left"
            show-overflow-tooltip
            >
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel()">取 消</el-button>
        <el-button type="primary" @click="submit()">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script >
import {validatenull} from "@/utils/validate"
export default {
  data(){
    return{
      dialogVisible:false,
      tableData: [],
      multipleSelection:[],
      // 勾选中的行数据
      selectedData: []
    }
  },
  mounted () {

  },
  created() {
  },
  methods:{
    init(tableDataOrigin,parentTreeData){
      this.dialogVisible = true ;
      this.tableData = tableDataOrigin; //原数据
      this.parentTreeData=parentTreeData;//已有的树
      this.initData(this.tableData)
      console.log('tableDataOrigin---:',tableDataOrigin,'parentTreeData:',parentTreeData)
    },
    // 初始化数据
    initData (data, parentId) {
      data && data.length && data.forEach((item) => {
        // isSelect状态：true为选中状态，false为未选中状态 ，空字符串为未知状态
        item.isSelect = false // 默认为不选中
        parentId && (item.parentId = parentId)
        if (item.children && item.children.length) {
          this.initData(item.children, item.id)
        }
      })
    },
    // 监听选中事件
    selectionChangeFun (selection) {
      this.selectedData = selection
    },
    // 复选框点击事件
    selectFun (selection, row) {
      this.setRowIsSelect(row)
    },
    // 复选框点击事件
    setRowIsSelect (row) {
      // 为空字符串则对应行半选态，点击则应该变为全选，则为true
      if (row.isSelect === '') {
        this.$refs.multipleTable.toggleRowSelection(row, true)
      }
      row.isSelect = !row.isSelect
      const _this = this
      // 判断操作的是子级点复选框还是父级点复选框，如果是父级点，则控制子级点的全选和不全选

      // 1、只是父级 2、既是子集，又是父级 3、只是子级
      const levelStatus = getCurrentLevel(row)

      if (levelStatus === 1) {
        // 操作的是父级，则所有子集同步父级状态
        selectAllChildren(row.children)
      } else if (levelStatus === 2) {
        selectAllChildren(row.children)
        operateLastLevel(row)
      } else if (levelStatus === 3) {
        operateLastLevel(row)
      }
      // 判断当前操作行的层级状态
      function getCurrentLevel (row) {
        // 1、只是父级 2、既是子集，又是父级 3、只是子级
        if (row.parentId === undefined) {
          return 1
        } else if (row.parentId && !(row.children && row.children.length)) {
          return 3
        } else {
          return 2
        }
      }

      // 递归处理children子级数据的isSelect状态以及对选框状态
      function selectAllChildren (children) {
        children && children.length && children.forEach((item) => {
          item.isSelect = row.isSelect
          _this.toggleRowSelection(item, row.isSelect)
          if (item.children && item.children.length) {
            selectAllChildren(item.children)
          }
        })
      }
      // 子级向上操作父级状态
      function operateLastLevel (row) {
        // 操作的是子节点,则
        // 1、获取父节点
        // 2、判断子节点选中个数，如果全部选中则父节点设为选中状态，如果都不选中，则为不选中状态，如果部分选择，则设为不明确状态
        const item = getExplicitNode(_this.tableData, row.parentId)
        const selectStatusArr = getSelectStatus([], item.children)

        // 判断所有子集选中态，都为true则父级也选中，都为false则不选中，否则为半选
        const allSelected = selectStatusArr.every(selectItem => selectItem === true)
        const allUnselected = selectStatusArr.every(selectItem => selectItem === false)
        if (allSelected) {
          item.isSelect = true
          _this.toggleRowSelection(item, true)
        } else if (allUnselected) {
          item.isSelect = false
          _this.toggleRowSelection(item, false)
        } else {
          item.isSelect = ''
        }
        // 如果当前节点的parentId存在，则还有父级，继续递归往上一层操作
        if (item.parentId !== undefined) {
          operateLastLevel(item)
        }
      }
      // 递归获取所有子级的选中状态数组
      function getSelectStatus (selectStatusArr, children) {
        if (!children || !children.length) {
          return selectStatusArr
        }
        children.forEach((child) => {
          selectStatusArr.push(child.isSelect)
          if (child.children && child.children.length) {
            getSelectStatus(selectStatusArr, child.children)
          }
        })
        return selectStatusArr
      }

      // 获取明确父级的节点
      function getExplicitNode (tableData, parentId) {
        let result = null
        function findNode (data) {
          for (let i = 0; i < data.length; i++) {
            if (data[i].id === parentId) {
              result = data[i]
              break
            }
            if (data[i].children && data[i].children.length) {
              findNode(data[i].children)
            }
          }
        }
        findNode(tableData)
        return result
      }
    },
    // 表格全选事件
    selectAllFun (selection) {
      const firstLevelStatus = this.tableData.map(item => item.isSelect)
      // 判断一级是否是全选.如果一级产品全为true，则设置为取消全选，否则全选
      const isAllSelect = firstLevelStatus.every(status => status)
      // 设置所以一级和二级为选中状态
      this.tableData.forEach((item) => {
        item.isSelect = isAllSelect
        this.toggleRowSelection(item, !isAllSelect)
        this.selectFun(selection, item)
      })
    },
    // 设置当前行的选中态
    toggleRowSelection (row, flag) {
      if (row) {
        this.$nextTick(() => {
          this.$refs.multipleTable &&
          this.$refs.multipleTable.toggleRowSelection(row, flag)
        })
      }
    },
    // 表格行样式 当当前行的状态为不明确状态时，添加样式，使其复选框为不明确状态样式
    getRowClassName ({ row }) {
      if (row.isSelect === '') {
        return 'indeterminate'
      }
    },
    // 表格标题样式 当一级目录有为不明确状态时，添加样式，使其全选复选框为不明确状态样式
    getHeaderRowClassName ({ row }) {
      const isIndeterminate = this.tableData.some(item => item.isSelect === '')
      if (isIndeterminate) {
        return 'indeterminate'
      }
      return ''
    },
    submit(){


      //数据扁平树
      let originTable = this.treeToArray(this.tableData)
      let parentTable = this.treeToArray(this.parentTreeData)
      // let A = [{ id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" }];
      // let B = [{ id: 2, name: "Item 2" }, { id: 4, name: "Item 4" }];
      let idsToRemove2 = originTable.map(item => item.id);
      let idsToRemove = parentTable.map(item => item.id);

      console.log('idsToRemove2:',idsToRemove2,"idsToRemove", idsToRemove)
      let result = originTable.filter(item => !idsToRemove.includes(item.id));
      result.map(item=>{
        delete item.children
      })
      console.log("比较的结果:",result);
      this.buildTree2(result)
      // originTable.filter(item => {
      //    parentTable.map(item.isSelect)
      // })
      console.log("组成的树结果:",this.buildTree3(result))


      this.$emit('sendSelectRow',this.buildTree3(result))
      this.cancel()
    },
    cancel(){
      this.selectedData = []
      this.dialogVisible = false ;
      this.$emit('close',close)
    },

    /**
     * 数据扁平化
     * @param tree
     * @returns
     */
    treeToArray(tree) {
      let res = []
      for (const item of tree) {
        const { children, ...i } = item
        if (children && children.length) {
          res = res.concat(this.treeToArray(children))
        }
        res.push(i)
      }
      return res
    },
    buildTree3(array, parentId = null) {
      let treeMap = new Map()

      array.filter(item => item.parentId === parentId).forEach(item => treeMap.set(item.id, { ...item, children: this.buildTree(array, item.id) }))

      return Array.from(treeMap.values())
    },

    buildTree2(list) {
      let temp = {};
      let tree = {};
      for (let i in list) {
        temp[list[i].id] = list[i];
      }
      for (let i in temp) {
        if (temp[i].parent_id) {
          if (!temp[temp[i].parent_id].children) {
            temp[temp[i].parent_id].children = new Object();
          }
          temp[temp[i].parent_id].children[temp[i].id] = temp[i];
        } else {
          tree[temp[i].id] = temp[i];
        }
      }
    },

    buildTree(data) {
      const map = {};
      const roots = [];

      // 创建一个map对象，key为id，value为整个对象
      data.forEach(node => {
        map[node.id] = { ...node, children: [] };
      });

      // 遍历原始数据，根据parentId找到对应的父节点，并将当前节点添加到其children数组中
      for (const node of data) {
        if (node.parentId === null) {
          roots.push(map[node.id]);
        } else {
          if (map[node.parentId]) {
            map[node.parentId].children.push(map[node.id]);
          }
        }
      }

      return roots;
    },

    handleSelectable(row, index) {
      // 如果状态不等于 '0'，则不允许选择
      return !row.disabled;
    },



  }
}
</script>

<style  scoped>
.indeterminate .el-checkbox__input .el-checkbox__inner {
  background-color: #409eff !important;
  border-color: #409eff !important;
  color: #fff !important;
}

.indeterminate .el-checkbox__input.is-checked .el-checkbox__inner::after {
  transform: scale(0.5);
}

.indeterminate .el-checkbox__input .el-checkbox__inner {
  background-color: #f2f6fc;
  border-color: #dcdfe6;
}

.indeterminate .el-checkbox__input .el-checkbox__inner::after {
  border-color: #c0c4cc !important;
  background-color: #c0c4cc;
}

.indeterminate .el-checkbox__input .el-checkbox__inner::after {
  content: '';
  position: absolute;
  display: block;
  background-color: #fff;
  height: 2px;
  transform: scale(0.5);
  left: 0;
  right: 0;
  top: 5px;
  width: auto !important;
}
</style>

